package com.renu.jdependencyanalyser.utils;



import com.renu.jdependencyanalyser.model.JarNode;

import java.io.*;
import java.util.ArrayList;
import java.util.List;



public class MavenUtil {
    private  static  final  String mvn = "mvn";

    private static  final  int info_len = 7;

    private static  final  int indent_len = 3;


    private static  int cnt ;
    public static JarNode getDependencyRoot (String projectPath) {
        // 运行 mvn dependency:tree 命令获取依赖树文本输出
        List<String> dependencyTreeLines = runMavenDependencyTree(projectPath);

        // 解析依赖树
        cnt = 0 ;
        JarNode rootNode = new JarNode();
        parseDependencyTree(dependencyTreeLines, rootNode,0);

        return rootNode.getChildren().get(0);


    }



    private static List<String> runMavenDependencyTree(String  projectDir) {
        // Maven 项目目录
        List<String> result = new ArrayList<>();

        try {
            // 执行 Maven 命令并将输出重定向到文件
            ProcessBuilder processBuilder = new ProcessBuilder(mvn,"-f" , projectDir,"dependency:tree");
            Process process = processBuilder.start();
            processBuilder.directory(new File(projectDir));

            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.matches("\\[INFO\\] .+:jar:.+"))
                    result.add(line);
            }

            process.waitFor();


        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        return result;
    }


    // 按照缩进进行解析
    private static void parseDependencyTree(List<String> treeLines, JarNode parent, int depth) {
        if (cnt >= treeLines.size()){
            return;
        }
        String line = treeLines.get(cnt++);
        String[] parts = line.split("\\s+");
        String coordinates = parts[parts.length - 1];
        int index = line.indexOf(coordinates);
        int curDepth = (index-info_len)/indent_len;
        if (curDepth<depth){
            cnt --;
            JarNode p = findParent(parent,depth - curDepth );
            parseDependencyTree(treeLines,p,curDepth);
            return ;
        }

        String[] coordinatesParts = coordinates.split(":");
        String group = coordinatesParts[0];
        String artifact = coordinatesParts[1];
        String version = coordinatesParts[3];
        JarNode jarNode = new JarNode(group, artifact, version,cnt);
        parent.getChildren().add(jarNode);
        jarNode.setParent(parent);
        parseDependencyTree(treeLines, jarNode,depth+1);




    }

    private static JarNode findParent(JarNode node, int depth) {
        if (depth == 0){
            return node;
        }
        return findParent(node.getParent(),depth-1);
    }


}
